#!/usr/local/bin/python3
# -*- coding: utf-8 -*-

"""
@File    : 横向柱状图测试.py
@Author  : Link
@Time    : 2022/4/30 16:55
@Mark    : 
"""
import pandas as pd
from pyqtgraph import ViewBox, Point
from pyqtgraph.dockarea import DockArea, Dock

"""
Simple example using BarGraphItem
"""

import numpy as np

import pyqtgraph as pg
from pyqtgraph.Qt import QtWidgets, QtCore
import pyqtgraph.functions as fn

x = np.arange(10)
y1 = np.sin(x)
y2 = 1.1 * np.sin(x + 1)
y3 = 1.2 * np.sin(x + 2)

"""
Simple example using BarGraphItem
"""

"""
导入一份数据
"""
df = pd.read_csv("distribution_trans.csv")


class PlotWidget(pg.PlotWidget):
    def keyPressEvent(self, ev):
        print(ev)
        super().keyPressEvent(ev)

    def keyReleaseEvent(self, ev):
        print(ev)
        print("Release")


class CustomViewBox(pg.ViewBox):
    select_signal = QtCore.Signal(object)

    def __init__(self, *args, **kwds):
        kwds['enableMenu'] = False
        pg.ViewBox.__init__(self, *args, **kwds)
        self.setMouseMode(self.RectMode)

    ## reimplement right-click to zoom out
    def mouseClickEvent(self, ev):
        if ev.button() == QtCore.Qt.MouseButton.RightButton:
            ev.ignore()
            # self.autoRange()

    def wheelEvent(self, ev, axis=None):
        if axis is None:
            ev.ignore()
            return
        super().wheelEvent(ev, axis)

    ## reimplement mouseDragEvent to disable continuous axis zoom
    def mouseDragEvent(self, ev, axis=None):
        # print(ev.button())
        if axis is not None and ev.button() in [QtCore.Qt.MouseButton.RightButton,
                                                QtCore.Qt.MouseButton.MiddleButton]:
            ev.ignore()
        else:
            self._mouseDragEvent(ev, axis=axis)

    def _mouseDragEvent(self, ev, axis=None):
        ev.accept()  ## we accept all buttons

        pos = ev.scenePos()
        dif = pos - ev.lastScenePos()
        dif = dif * -1

        ## Ignore axes if mouse is disabled
        mouseEnabled = np.array(self.state['mouseEnabled'], dtype=np.float64)
        mask = mouseEnabled.copy()
        if axis is not None:
            mask[1-axis] = 0.0

        if ev.button() in [QtCore.Qt.MouseButton.LeftButton, QtCore.Qt.MouseButton.MiddleButton]:
            if self.state['mouseMode'] == ViewBox.RectMode and axis is None:
                if ev.isFinish():  ## This is the final move in the drag; change the view scale now
                    print("finish")
                    self.rbScaleBox.hide()
                    ax = QtCore.QRectF(Point(ev.buttonDownScenePos(ev.button())), Point(pos))  # 这个是坐标数据
                    ax = self.childGroup.mapRectFromParent(ax)  # 换算成实际数据
                    self.select_signal.emit(ax)
                    # self.showAxRect(ax)
                    self.axHistoryPointer += 1
                    self.axHistory = self.axHistory[:self.axHistoryPointer] + [ax]
                else:
                    ## update shape of scale box
                    self.updateScaleBox(ev.buttonDownScenePos(), ev.scenePos())
            else:
                tr = self.childGroup.transform()
                tr = fn.invertQTransform(tr)
                tr = tr.map(dif * mask) - tr.map(Point(0, 0))

                x = tr.x() if mask[0] == 1 else None
                y = tr.y() if mask[1] == 1 else None

                self._resetTarget()
                if x is not None or y is not None:
                    self.translateBy(x=x, y=y)
                self.sigRangeChangedManually.emit(self.state['mouseEnabled'])


# Final example shows how to handle mouse clicks:
class BarGraph(pg.BarGraphItem):
    def mouseClickEvent(self, event):
        print("clicked")


def select_range(ax: QtCore.QRectF):
    """
    只看x
    :param ax:
    :return:
    """
    print(ax)


app = pg.mkQApp()
win = QtWidgets.QMainWindow()
area = DockArea()
win.setCentralWidget(area)
win.resize(1000, 500)

axis = pg.AxisItem(orientation='bottom')
vb = CustomViewBox()
vb.select_signal.connect(select_range)
pw = PlotWidget(viewBox=vb, enableMenu=False,
                title="PlotItem with DateAxisItem, custom ViewBox and m")
print("""无敌""")

showminy = 0
showmaxy = 10

bg = BarGraph(x0=[], y=[], y0=[], y1=[], width=[], brush='r')
pw.addItem(bg)
bottom_axis = pw.getAxis("bottom")
bottom_axis.setHeight(60)

left_axis = pw.getAxis("left")
left_axis.setWidth(60)


def bar_update():
    """
    这里面要优化,
        1. 一定要尽量减少变化的次数, 可以延迟一会儿
        2. 使用1000 为一个步进单位
    :return:
    """
    temp_df = df[(df["2010:VOL_VREG1_LOW   JUDGE_VARIABLE_MS"] > showminy) & (
            df["2010:VOL_VREG1_LOW   JUDGE_VARIABLE_MS"] < showmaxy)]
    if len(temp_df) == 0:
        return
    columns = []
    c = 0
    x0 = []
    y0 = []
    y1 = []
    y = []
    _max = 0
    width = []
    for key, e_df in temp_df.groupby("GROUP"):
        temp_dis = e_df['2010:VOL_VREG1_LOW   JUDGE_VARIABLE_MS'].value_counts(bins=30)
        print(temp_dis)
        columns.append(key)
        _max = max(temp_dis) if max(temp_dis) > _max else _max
        # _sum = sum(temp_dis)
        for index, value in temp_dis.items():
            x0.append(c + 0.2)
            y0.append(index.left)
            y1.append(index.right)
            y.append((index.left + index.right) / 2)
            width.append(value)

        c = c + 1
    x0 = np.array(x0) * _max
    # columns = ["C\r\nDE", "E\r\nDE"]
    ticks = [((idx + 0.2) * _max, label.replace("-", "\r\n")) for idx, label in enumerate(columns)]
    bg.setOpts(x0=x0, y=y, y0=y0, y1=y1,
               width=width, brush=(217,83,25,125))
    bottom_axis.setTicks((ticks, []))
    vb.setXRange(0, c * _max * 1.2)


bar_update()


def updateRegion(a, lineshow):
    print(lineshow)
    global showminy
    global showmaxy
    if lineshow[1][1] - lineshow[1][0] == showmaxy - showminy:
        return
    showminy = lineshow[1][0]
    showmaxy = lineshow[1][1]

    # 如果showmaxy - showminy没变, 就不管

    bar_update()


pw.sigRangeChanged.connect(updateRegion)

" ================ mapping"
vb2 = CustomViewBox()
vb2.select_signal.connect(select_range)
pw2 = PlotWidget(viewBox=vb2, enableMenu=False,
                 title="PlotItem with DateAxisItem, custom ViewBox and m")
s3 = pg.ScatterPlotItem(
    pxMode=False,  # Set pxMode=False to allow spots to transform with the view
    hoverable=True,
    hoverPen=pg.mkPen('g'),
    hoverSize=1e-6
)
spots3 = []
for i in range(10):
    for j in range(10):
        spots3.append({'pos': (1e-6 * i, 1e-6 * j), 'size': 1e-6, 'pen': {'color': 'w', 'width': 2},
                       'brush': pg.intColor(i * 10 + j, 100)})
s3.addPoints(spots3)
pw2.addItem(s3)

d1 = Dock("Dock1", size=(1, 1))
area.addDock(d1, 'left')
d2 = Dock("Dock2", size=(1, 1))
area.addDock(d2, 'right')
d1.addWidget(pw)
d2.addWidget(pw2)

win.show()
if __name__ == '__main__':
    pg.exec()
